import type { MutableRefObject } from 'react';
import { useContext, useState } from 'react';
import { useQuery } from '@tanstack/react-query';
import { queryHistory } from '@/services/api';
import type diff_match_patch from 'diff-match-patch';
import type { IHistory } from '@/interfaces';
import sanitizeHtml from 'sanitize-html';
import { flushSync } from 'react-dom';
import Alert from '@/app/[locale]/alert/alert';
import AlertLoad from '@/app/[locale]/alert/load';
import ContentHtml from '@/app/[locale]/common/content/html';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import Nodata from '@/app/[locale]/common/nodata/nodata';
import { PostEditContext } from '@/contexts/post-edit';

export type TViewHistoryTranslatedField =
  | 'namePlaceholder'
  | 'save'
  | 'saveCompleted'
  | 'restore'
  | 'difference'
  | 'overview'
  | 'content'
  | 'name';

export default function ViewHistory({
  id,
  diffMatchPatchRef,
  translatedFields = {
    namePlaceholder: '请输入版块名称',
    save: '保存',
    saveCompleted: '保存完成',
    restore: '恢复',
    difference: '差异',
    name: '名称',
    overview: '概述',
    content: '内容',
  },
}: {
  id: number;
  diffMatchPatchRef: MutableRefObject<diff_match_patch | undefined>;
  translatedFields?: Record<TViewHistoryTranslatedField, any>;
}) {
  const { onNavItemName } = useContext(PostEditContext);
  const [loadDiff, setLoadDiff] = useState(false);
  const [diffText, setDiffText] = useState('');
  const pathname = usePathname();

  const queryHistoryQuery = useQuery(
    ['/forum', '/histories', id],
    async (context) => {
      return (await queryHistory({
        id: context.queryKey[2] + '',
      })) as IHistory;
    },
    {
      enabled: !!id,
    },
  );

  function cleanupContent(content: string = '') {
    return sanitizeHtml(content, {
      allowedTags: [],
    });
  }

  function onClickDiff() {
    const item = queryHistoryQuery.data;
    if (!item || loadDiff || !diffMatchPatchRef || !diffMatchPatchRef.current) {
      return;
    }

    const oldContent = item.content;
    if (!oldContent) {
      return;
    }

    const newContent = '';
    if (!newContent) {
      return;
    }

    flushSync(() => {
      setLoadDiff(true);
      const current = diffMatchPatchRef.current!;
      const diffMain = current.diff_main(
        cleanupContent(oldContent),
        cleanupContent(newContent),
      );
      current.diff_cleanupSemantic(diffMain);
      const html = current.diff_prettyHtml(diffMain);
      setDiffText(html);
      setLoadDiff(false);
    });
  }

  function onClickRestore() {
    onNavItemName('编辑');
  }

  if (queryHistoryQuery.data) {
    const data = queryHistoryQuery.data;

    return (
      <div className="vstack gap-4 mt-5">
        <div className="hstack flex-wrap align-items-center gap-2">
          <button
            disabled={loadDiff}
            className="btn btn-primary"
            onClick={onClickDiff}
          >
            {loadDiff ? (
              <span
                className="spinner-border spinner-border-sm me-2"
                role="status"
                aria-hidden="true"
              ></span>
            ) : (
              <i className="bi bi-plus-slash-minus me-2"></i>
            )}
            {translatedFields.difference}
          </button>
          <Link
            onClick={onClickRestore}
            className="btn btn-primary"
            href={pathname.replace('/history', `?history=${id}`)}
          >
            <i className="bi bi-box-arrow-in-left me-2"></i>
            {translatedFields.restore}
          </Link>
        </div>

        <div className="card">
          <div className="card-header">{translatedFields.name}</div>
          <div className="card-body">{data.name ? data.name : <Nodata />}</div>
        </div>

        <div className="card">
          <div className="card-header">{translatedFields.overview}</div>
          <div className="card-body">
            {data.overview ? (
              <ContentHtml content={data.overview} />
            ) : (
              <Nodata />
            )}
          </div>
        </div>

        <div className="row g-4">
          <div className="col">
            <div className="card">
              <div className="card-header">{translatedFields.difference}</div>
              <div className="card-body">
                {diffText ? (
                  <div dangerouslySetInnerHTML={{ __html: diffText }} />
                ) : (
                  <Nodata />
                )}
              </div>
            </div>
          </div>
          <div className="col">
            <div className="card">
              <div className="card-header">{translatedFields.content}</div>
              <div className="card-body">
                {data.content ? (
                  <ContentHtml content={data.content} />
                ) : (
                  <Nodata />
                )}
              </div>
            </div>
          </div>
        </div>
      </div>
    );
  }

  if (queryHistoryQuery.error) {
    return <Alert type="error" message={queryHistoryQuery.error} />;
  }

  return <AlertLoad />;
}
